(async function () {
/**
* 1.0 与 2.0脚本的主要区别如下
* @param {shopId} - 获取都在init()中,但是操作略有不同
* @function (renderButton) - 1.0是insertAdjacentHTML, 2.0由于是挂在到liquid,主要采取替换innerHTML
*
*
*/
// warning : .shopify-payment-button 字符串被用于替换做兼容
/**
* 脚本是否运行过,运行过则退出
*/
// 脚本有三种,没更新的写入脚本,更新的写入脚本和扩展脚本
// 更新的写入脚本和扩展脚本同时出现时,更新的写入脚本先执行,扩展脚本会在这退出
if (typeof bis_shopify_block_status !== "undefined") {
if (bis_shopify_block_status === 1) {
return;
} else if (bis_shopify_block_status === 2) {
bis_shopify_block_status = 1;
}
}
const scripts = document.querySelectorAll(
'script[src*="/assets/product_restore_email.js"]'
);
// 没更新的写入脚本并没有这俩个判断退出,默认执行,所以扩展脚本识别到有没更新的写入脚本得退出
if (scripts.length === 2 && scripts[0].src.indexOf("extensions") === -1) {
return;
}
// 防抖
function debounce(delay = 500, callback) {
let timer;
return function () {
clearTimeout(timer);
timer = null;
timer = setTimeout(() => {
callback();
}, delay);
};
}
// Mark 变量声明
let isProPage = false;
let isCollPage = false;
let productId = 0;
let insertEls = [];
let collVariants = [];
let observer = null;
let oldCollElsCount = 0;
let proPosition = [];
let locale;
let customStyle = "";
let customPosition = null;
let customFeature = null;
let collectionAccess = false;
const themeId = Shopify.theme.id;
let executeDelay = 0;
let v = { executeDelay: 0, variantListenerElement: "" };
let u = { insert_button_info: {}, custom_style_info: {} };
let updateStatus = {
is_button_settings_updating: 1,
is_popup_settings_updating: 1,
is_integrations_updating: 1,
is_variants_updating: 1,
button_status: 1,
lang_status: 1,
}; // 获取所有数据的更新情况,是否要请求接口
let observerCallback = null;
let getDataCount = 0; // 获取数据成功的次数,相当于请求成功次数,分别是按钮样式、弹窗样式、集成数据、3次成功后开始嵌入按钮和弹窗
const productPageType = 1;
const collectionPageType = 2;
const pageType =
ShopifyAnalytics &&
ShopifyAnalytics.meta &&
ShopifyAnalytics.meta.page &&
ShopifyAnalytics.meta.page.pageType;
let insertType = "afterend";
let emailStyle = null;
const isMobile =
/(iPhone|iPad|iPod|iOS|Android|SymbianOS|Windows Phone|webOS|BlackBerry)/i.test(
navigator.userAgent
);
if (typeof ShopifyAnalytics === "undefined") {
await new Promise((res, rej) => {
setTimeout(() => {
res();
}, 1500);
});
}
if (window.ShopifyAnalytics && ShopifyAnalytics.meta.product) {
productId = ShopifyAnalytics.meta.product.id;
} else if (Shopify.designMode) {
if (!q("#em_product_id")) {
await new Promise((res, rej) => {
setTimeout(() => {
res();
}, 1000);
});
}
productId = JSON.parse(q("#em_product_id").textContent);
}
let shopId = 0;
if (qa("#shopify-features").length !== 0) {
shopId = JSON.parse(qa("#shopify-features")[0].outerText).shopId;
} else if (
window.ShopifyAnalytics &&
ShopifyAnalytics.lib &&
ShopifyAnalytics.lib.config
) {
shopId = ShopifyAnalytics.lib.config.Trekkie.defaultAttributes.shopId;
} else {
shopId = JSON.parse(q("#bis_shop_id").textContent);
}
// userNeed()
locale = Shopify.locale;
// Mark 相关请求
let requests = {
getProsVariantsData(p) {
const url = baseUrl + "api/v1/customer/getVariantBtStatus";
let params = {};
Object.assign(params, p);
return request(url, params);
},
getCollBtnStyle() {
const url = baseUrl + "api/v1/getCollectionButtonStyle";
let params = {
shop_language: locale,
};
return request(url, params);
},
/**
* 获取缺货变体数据
* @param {{product_ids?:number[];product_handles?:string[];page_type:number}} extraParams - 页面类型
*/
variantsData(extraParams = {}) {
const url =
bisBaseUrl + "api/v1/product/get_customer_variants_inventory_status";
let params = {
...extraParams,
};
return request(url, params, "GET");
},
/**
* 获取按钮设置
* @param {number} page_type - 页面类型
*/
buttonSettings(page_type) {
const url = bisBaseUrl + "api/v1/product/get_customer_button_settings";
let params = {
lang: locale,
page_type,
};
return request(url, params, "GET");
},
/**
* 获取弹窗设置
*/
popupSettings() {
const url = bisBaseUrl + "api/v1/product/get_customer_popup_settings";
let params = {
lang: locale,
};
return request(url, params, "GET");
},
integrationStatus() {
const url = bisBaseUrl + "api/v1/integration/get_customer_integrations";
return request(url, {}, "GET");
},
};
// 店铺域名
const domain = Shopify.shop;
/*
* dev下debug为true, baseUrl为测试服。
* prod下debug为false, baseUrl为正式服
*/
const baseUrl = bisApiBaseUrl;
const bisBaseUrl = TRUSTOO_BIS_BASE_URL;
// 登录用户的信息
let customerInfo = {};
// 能够展示按钮的变体数组
let showVariants = [];
// 按钮以及弹窗的参数
const btnAndPopupData = initBtnAndPopupData();
const {
buttonStyleUrl,
collButtonStyleUrl,
popupStyleUrl,
integrationUrl,
floatBtnPosition,
buttonData,
generalData,
formAction,
} = btnAndPopupData;
let {
iti,
popupData,
inlineBtnHeight,
inlineBtnWidth,
btnRadius,
btnFontSize,
btnFontWeight,
insertEl,
selectedType,
selBtnStatus,
btnStyleSwitch,
popupStyleSwitch,
inteStatus,
} = btnAndPopupData;
const elements = initElement();
let {
inlineBtnElement,
floatBtnElement,
emailFrameElement,
inlineEmailDiv,
floatEmailDiv,
invalidTip,
successFrame,
variantSelector,
closeBox,
submitBtn,
emailInput,
nameInput,
smsInput,
mailingCheckbox,
soldOutBtn,
exactForm,
} = elements;
const initRes = await init();
if (typeof initRes === "string") {
console.log("Init info: ", initRes);
//return; // 如果获得的返回值不是对象而是string,说明在中间的某一个if判断出问题了,应当直接return
} else {
console.log("App is on!");
}
const { MAX_SEARCH_TIMES } = initRes;
let { times } = initRes;
const { trueForms } = elements;
const productInfo = initProductInfo();
let {
currentVariant,
available,
selectVariantId,
productTitle,
currentVariantOption,
addOptionsStatus,
initUrl,
listenVariantFlag,
} = productInfo;
let { variantData, unVariantOptions } = productInfo;
const payment_button_class = ".shopify-payment-button";
execute();
importStyles(); // 引入邮件的css
// =====================================逻辑就到这里结束====================================
// =====================================逻辑就到这里结束====================================
// =====================================逻辑就到这里结束====================================
// Mark 初始化
async function init() {
/*
* 初始化一些店铺的信息,判断是否要继续往下执行脚本
* shopId - 店铺id,长的那个,不是user表里短的那个
* ENV - dev下debug为true, baseUrl为测试服。
* prod下debug为false, baseUrl为正式服
*/
// const ENV = 'prod';
// const baseUrl = ENV.indexOf('dev') === -1
// ? 'https://emailnoticeapi.sealapps.com/'
// : 'https://emailnoticeapitest.sealapps.com/';
// 从浏览器的window对象中获取ShopifyAnalytics对象
const { ShopifyAnalytics } = window;
let proParams = {};
let prosEle = [];
let prosEleHandle = [];
isProPage = pageType === "product" || q("#sealapps-bis-widget");
isCollPage = pageType === "collection" || collectionAccess;
v.isProPage = isProPage;
v.isCollPage = isCollPage;
if (!isCollPage && !isProPage) {
return "not collectionPage or productPage";
}
getUserNeedData();
if (u.custom_style_info.css_style_code) {
customStyle += u.custom_style_info.css_style_code;
}
addCustomModify();
// 运行前执行用户需求自定义函数
if (typeof bisBeforeExecute !== "undefined") {
bisBeforeExecute(v);
}
const delay = v.executeDelay || executeDelay;
if (delay !== 0) {
await new Promise((res, rej) => {
setTimeout(() => {
res();
}, delay);
});
}
setCollDeb();
const statusParams = {};
if (isProPage) {
statusParams.product_ids = [productId];
}
const statusRes = await request(
bisBaseUrl + "api/v1/shop/get_data_update_status",
statusParams,
"GET"
);
if (statusRes.code === 0) {
updateStatus = statusRes.data;
} else {
updateStatus = {
is_button_settings_updating: 1,
is_popup_settings_updating: 1,
is_integrations_updating: 1,
is_variants_updating: 1,
button_status: 1,
lang_status: 1,
};
}
if (isProPage) {
if (productId) {
proParams.product_ids = [productId];
proParams.page_type = 1;
}
} else if (isCollPage) {
prosEle = await getProsEle();
if (prosEle !== null) {
oldCollElsCount = prosEle.length;
prosEleHandle = getProductsANodes(prosEle);
prosEle = prosEleHandle.map((it) => it.element);
proParams.product_handles = prosEleHandle.map((it) => it.handle);
proParams.page_type = 2;
} else {
return "No embed location found";
}
}
await getButtonStyle(proParams.page_type);
// if (ShopifyAnalytics && ShopifyAnalytics.meta && ShopifyAnalytics.meta.page && ShopifyAnalytics.meta.page.pageType !== 'product') {
// return 'Not in product page';
// } else if (location.href.indexOf('product') === -1) {
// return 'Not in product page';
// }
// 获取shopId
// const shopId = ShopifyAnalytics.lib
// ? JSON.parse(qa('#shopify-features')[0].outerText).shopId
// : ShopifyAnalytics.lib.config.Trekkie.defaultAttributes.shopId;
changeStatus({ baseUrl });
// 获取需要显示按钮的产品数据
// await getProductStatus();
if (
buttonData.is_active_float_btn === 1 ||
buttonData.is_active_inline_btn === 1
) {
if (Object.keys(proParams).length !== 0) {
if (updateStatus.is_variants_updating !== 1 && !isCollPage) {
if (typeof bis_sold_out_variants !== "undefined") {
showVariants = bis_sold_out_variants[0].variants.map((variant) => {
return variant.variant_id;
});
} else {
showVariants = [
{
variants: [],
},
];
}
} else {
const res = await requests.variantsData(proParams);
// if (shopId == 48441458840 && proParams.page_type === 1) {
// } else if (res.btStatus !== 1) {
// return "collectionPage btn disable";
// }
const { code, data } = res;
const products = data.products;
if (isProPage) {
if (code === 0 && products) {
//由于是产品页,所以产品肯定只有一个
showVariants = products[0].variants.map((variant) => {
return variant.variant_id;
});
}
} else if (isCollPage) {
products.forEach((i, inx) => {
const target = prosEleHandle.find((it) => it.handle === i.handle);
if (target && i.variants.length !== 0) {
insertEls.push(target.element);
proPosition.push(inx);
collVariants.push({
proId: i.product_id,
productName: i.title,
variants: i.variants,
});
}
// if (i.productStatus === 1) {
// insertEls.push(prosEle[inx]);
// proPosition.push(inx);
// collVariants.push({
// proId: i.product_id,
// productName: i.title,
// variants: i.variants,
// });
// }
});
}
}
}
} else {
return "Button is disabled";
}
const hasUnavailableV = showVariants.length || collVariants.length;
if (hasUnavailableV == 0) {
if (isCollPage) {
// 这页产品列表没有,其他排序可能有,要设立监听
checkVariantChange();
}
return "All btn of variants are hidden.";
}
const nodes = qa(`#product-restore-email-float,.product-restore-email`);
if (nodes.length !== 0) {
if (!isCollPage) {
nodes.forEach((i) => i.remove());
}
// return 'Already enabled';
} else {
const div = `
`;
document.body.insertAdjacentHTML("beforeend", div);
}
return {
baseUrl,
MAX_SEARCH_TIMES: 50,
times: 0,
};
}
// Mark 执行
async function execute() {
if (isProPage) {
// // 获取需要显示按钮的产品数据
// await getProductStatus(baseUrl);
if (showVariants.length === 0) {
return;
}
if (insertEl) {
handleBasicData();
getAllData();
} else {
searchParentEl().then((res) => {
const { code } = res;
if (code === 501) {
// 没有找到元素,打印出来,方便人员调试
console.log("Search Node Failed");
handleSearchNodeFailed().then((searchRes) => {
if (searchRes.code === 0) {
handleBasicData();
getAllData();
}
});
return;
}
if (code === 0) {
// 找到了插入的元素,继续往下执行
handleBasicData();
getAllData();
}
});
}
} else if (isCollPage) {
if (buttonData.is_active_inline_btn === 1) {
getAllData();
}
}
}
//Mark 获取集合页产品列表的嵌入元素(价格)
async function getProsEle() {
const themeStoreId = Shopify.theme.theme_store_id;
let selector = "";
if (
buttonData.customize_inline_btn_position === 1 &&
buttonData.insert_element_selector
) {
selector = buttonData.insert_element_selector;
} else if (Object.keys(u.insert_button_info).length !== 0) {
selector = u.insert_button_info.selector;
insertType = u.insert_button_info.position;
} else {
switch (themeStoreId) {
/*
Dawn-887 Refresh-1567 Sense-1356 Crave-1363
Craft-1368 Studio-1431 Taste-1434 Ride-1500
Colorblock-1499
*/
case 887:
case 1567:
case 1356:
case 1363:
case 1368:
case 1431:
case 1434:
case 1500:
case 1499:
case 1399: {
selector = ".card-information .price";
// selector = '.grid__item .card';
// const el = qa(selector);
// el.forEach(eachEl => {
// eachEl.style.height = 'unset';
// eachEl.style.position = 'relative';
// });
break;
}
case 829: {
// Narrative
selector = ".card__info>.card__price";
break;
}
case 775: {
// Venture
selector = ".product-card__info>.product-card__price";
break;
}
case 796: {
// Debut
selector = ".product-card>.price";
break;
}
case 730: {
// Brooklyn
selector = ".grid__item .grid-product__price-wrap";
break;
}
case 679: {
// Supply
selector = ".grid-item .product-item--price";
break;
}
case 380: {
// Minimal
selector = ".grid__item .grid-link__meta";
break;
}
case 578: {
//Simple
selector = ".grid__item .product__prices";
break;
}
case 857: {
selector = ".grid__item .grid-product__price";
break;
}
case 765: {
selector = ".product--details";
break;
}
case 849: {
selector = ".product-block__info";
break;
}
case 459: {
selector = ".product-info-inner .price";
break;
}
default: {
// Warehouse主题
if (q("body.warehouse--v1")) {
selector = ".product-item .product-item__price-list";
} else {
switch (themeId) {
// Insomniac主题
case 129555497130:
selector = ".collection-grid-item__meta";
break;
// energy主题
case 139843010841:
selector = ".product-item-meta";
break;
// Booster_3_0
case 117705834682:
selector = ".grid-view-item";
break;
case 3639214169: {
selector = ".product-index .product-info";
break;
}
}
if (shopId === 3639214169 && themeId === 139935711534) {
selector = ".product-index .product-info";
} else if (shopId === 61058973863 && themeId === 130619900071) {
selector = ".product-block .product-info";
} else if (shopId === 71594410265 && themeId === 143828386073) {
selector = ".product-item__info-inner";
} else if (shopId === 68210557218 && themeId === 142585594146) {
selector = ".card-information .price";
} else if (shopId === 25981404 && themeId === 132703387810) {
selector = ".product-item-meta";
} else if (shopId === 66663121193 && themeId === 139562189097) {
selector = ".product-item-meta";
} else if (shopId === 2797404227 && themeId === 122716946499) {
selector = ".price.price--sold-out";
} else if (shopId === 73514025266 && themeId === 146007327026) {
selector = ".product-item__price-list.price-list";
} else if (shopId === 25981404 && themeId === 132868636834) {
selector =
".product-item__cta.button.button--secondary.hidden-phone";
}
}
}
}
}
if (shopId === 72470462767 && themeStoreId === 1399) {
selector = ".card-information__button";
insertType = "afterbegin";
}
if (selector) {
const nodes = Array.from(qa(selector));
if (nodes.length == 0) {
await new Promise((res, rej) => {
setTimeout(() => {
res();
}, 1500);
});
}
return nodes.filter(
(i) => i.offsetParent !== null && !i.getAttribute("bis-inserted")
);
} else {
return null;
}
}
// 获取集合页产品列表的handle
function getProsHandles(node) {
let productHandleStrings = "";
let handleArr = [];
let handle = "";
// if (nodes.length) {
let tarEle = "A";
// for (let i = 0; i < nodes.length; i++) {
if (node && node.tagName === tarEle && node.getAttribute("href")) {
let href = node.getAttribute("href");
let start = href.lastIndexOf("/products/") + 10;
let end = href.indexOf("?");
if (end != -1) {
handle = href.substring(start, end);
} else {
handle = href.substring(start);
}
if (handle.indexOf(".jpg") === -1) {
handle = decodeURI(handle);
// handleArr.push(handle);
}
}
// }
// productHandleStrings = handleArr.join(',')
// }
// productHandleStrings = productHandleStrings.replace(/[#]/g, '')
return handle;
}
// Mark 获取集合页产品A元素
function getProductsANodes(nodes) {
let lists = {
aNodeList: [],
prosEle: [],
};
const list = [];
let aNodeList = [];
let index = 0;
// collTarget = Array.from(collTarget)
let hs = 'a[href*="/products/"]';
let tarEle = "A";
let curNode = nodes[0];
let aNode;
for (let i = 0; i < nodes.length; i++) {
curNode = nodes[i];
aNode = null;
for (let j = 0; j < 5; j++) {
curNode = curNode.parentNode;
if (
curNode.tagName === tarEle &&
curNode.href &&
curNode.href.indexOf("/products/") !== -1
) {
aNode = curNode;
break;
}
let childA = q(hs, curNode);
if (childA) {
aNode = childA;
break;
}
}
if (aNode) {
list[index] = {
element: nodes[i],
handle: getProsHandles(aNode),
};
index++;
lists.prosEle.push(nodes[i]);
lists.aNodeList.push(aNode);
} else {
nodes[i] = null;
}
}
return list;
}
// Mark 初始化产品信息
function initProductInfo() {
/*
* 初始化一些店铺的信息,比如
* variantData - 该产品所有的变体信息数组
* currentVariant - 当前/默认选中的变体,偶尔可能会与实际情况有差别
* available - 当前变体是否available
* selectVariantId - 被选中的变体的id
* hasAvailableV - 是否有缺货的变体
* unVariantOptions - 缺货的变体,用于之后生成弹窗中的select的options
* currentVariantOption - 当前选中的变体
* addOptionsStatus - 似乎是用于记录是否选择了变体的状态
*/
let info = {
selectVariantId: "",
unVariantOptions: [],
currentVariantOption: null,
addOptionsStatus: 0,
productTitle: "",
initUrl: document.URL,
};
if (isProPage) {
const variantData = JSON.parse(q("#em_product_variants").textContent);
const hasAvailableV = variantData.some((v) => v.available === false);
const currentVariant = JSON.parse(
q("#em_product_selected_or_first_available_variant").textContent
);
Object.assign(info, {
variantData,
currentVariant,
available: currentVariant.available,
selectVariantId: currentVariant.id,
hasAvailableV,
listenVariantFlag: true,
});
}
return info;
}
// Mark 初始化按钮和弹窗
function initBtnAndPopupData() {
// 初始化按钮以及弹窗的相关数据
return {
btnRadius: "",
btnFontSize: "",
inlineBtnWidth: "",
inlineBtnHeight: "",
btnFontWeight: "initial",
popupStyleUrl: "getPopupStyle",
buttonStyleUrl: "getButtonStyle",
collButtonStyleUrl: "getCollectionButtonStyle",
integrationUrl: "integrate/getIntegration",
floatBtnPosition: "float-btn-right",
buttonData: {
inline_btn_text: "",
inline_btn_bg_color: "",
inline_text_color: "",
inline_btn_margin_top: "",
inline_btn_margin_bottom: "",
collection_btn_value: "",
collection_is_show: 0,
is_active_inline_btn: 0,
float_btn_text: "",
float_btn_bg_color: "",
float_text_color: "",
customize_inline_btn_position: 0,
insert_element_selector: "",
insert_type: "",
float_offset: 0,
is_active_float_btn: 0,
is_branding_removed: 0,
},
generalData: {
display_all: 0, // 只要有一个变体缺货,展示给所有变体
font_family: "inherit",
font_size: "14",
font_weight: "inherit",
horizontal_animation: 0,
hover_bg_color: "#333333",
hover_text_color: "#ffffff",
inline_btn_margin_top: "0",
inline_btn_margin_bottom: "0",
border_radius: "0",
border_color: "transparent",
customize_css: "",
},
popupData: null,
frameBtnColor: "#333333",
frameBtnFontColor: "#ffffff",
insertType: "afterend",
insertEl: null,
selectedType: {},
iti: null, // intl-phone-input插件
selBtnStatus: 0, // selBtnStatus返回情况
btnStyleSwitch: 0, // buttonStyle是否请求成功
popupStyleSwitch: 0, // popupStyle是否请求成功
inteStatus: 0, // 是否开启集成商
formAction: "https://" + document.domain + "/cart/add", // 用于验证form表单的action
};
}
function initElement() {
return {
inlineBtnElement: null,
floatBtnElement: null,
emailFrameElement: null,
inlineEmailDiv: null,
floatEmailDiv: null,
invalidTip: null,
successFrame: null,
variantSelector: null,
closeBox: null,
submitBtn: null,
soldOutBtn: null,
emailInput: null,
nameInput: null,
smsInput: null,
mailingCheckbox: null,
trueForms: [],
exactForm: null,
};
}
//Mark 获取按钮样式
function getBtnStyle(btn) {
if (btn.tagName == "DIV") {
btn = btn.querySelector("button");
}
if (!btn) {
return;
}
const btnStyle = window.getComputedStyle(btn, null);
if (btnStyle.width == "auto" || !btnStyle.width) {
inlineBtnWidth = "";
} else if (btnStyle.width.indexOf("px") !== -1) {
if (parseFloat(btnStyle.width) > 120) {
inlineBtnWidth = btnStyle.width;
}
}
if (btnStyle.height == "auto" || !btnStyle.height) {
inlineBtnHeight = "";
} else {
inlineBtnHeight = btnStyle.height;
}
btnRadius = btnStyle.borderRadius;
btnFontSize = btnStyle.fontSize;
btnFontWeight = btnStyle.fontWeight;
}
// 获取soldout按钮以及样式
function getSoldOutBtn(trueForm) {
const btnArr = trueForm.querySelectorAll("button");
const iptArr = [
...trueForm.querySelectorAll("input[type='submit']"),
...trueForm.querySelectorAll("input[type='button']"),
];
const allArr = [...btnArr, ...iptArr];
if (allArr.length) {
for (let i = 0; i < allArr.length; i++) {
if (
(allArr[i].type == "submit" && allArr[i].name == "add") ||
(allArr[i].type == "submit" && allArr[i].name == "button")
) {
soldOutBtn = allArr[i];
break;
}
}
if (!soldOutBtn) {
for (let i = 0; i < allArr.length; i++) {
if (allArr[i].type == "submit") {
soldOutBtn = allArr[i];
break;
}
}
}
if (!soldOutBtn) {
for (let i = 0; i < allArr.length; i++) {
if (allArr[i].disabled) {
soldOutBtn = allArr[i];
break;
}
}
}
if (!soldOutBtn) {
soldOutBtn = allArr[0];
}
soldOutBtn && getBtnStyle(soldOutBtn);
}
}
// 找shopify_payment_button以及parent
function searchParentEl() {
return new Promise((resolve) => {
// 首先获取所有的form,并进行遍历
const forms = qa("form");
for (let i = 0; i < forms.length; i++) {
// 如果当前表单的action与预测的formAction相同,则推入trueForms数组
if (forms[i].action.indexOf("/cart/add") !== -1) {
trueForms.push(forms[i]);
}
}
if (!trueForms.length) {
resolve({ code: 501, msg: "Search el failed" });
}
// 如果只有一个form表单的action与预期的相同,则一定为要添加按钮的form
if (trueForms.length == 1) {
exactForm = trueForms[0];
getSoldOutBtn(trueForms[0]);
} else {
// 对遍历得出的action符合预期的form数组再次进行循环
for (let i = 0; i < trueForms.length; i++) {
if (soldOutBtn) {
break;
}
const formStyle = window.getComputedStyle(trueForms[i], null);
// 如果form不显示的话,直接中断本次循环,继续遍历之后的form表单
if (
formStyle.visibility != "visible" ||
formStyle.display == "none" ||
formStyle.height == "0px" ||
formStyle.height == "0" ||
formStyle.width == "0px" ||
formStyle.width == "0" ||
formStyle.height == "auto"
) {
continue;
}
exactForm = trueForms[i];
getSoldOutBtn(trueForms[i]);
// 有可能在第一次内层btnArr循环的时候已经取得了shopify_payment_button,要考虑父级是否有正常显示。
if (soldOutBtn) {
const parent = soldOutBtn.parentElement;
const parentStyle = window.getComputedStyle(parent, null);
// 如果父级正常的话就结束trueForms循环
if (
parentStyle.visibility == "visible" &&
parentStyle.display != "none" &&
parentStyle.height != 0 &&
parentStyle.width != 0
) {
break;
}
}
// 在该form中寻找是否存在shopify payment button,有的话结束循环,没有的话开始遍历所有按钮寻找对的按钮
soldOutBtn = trueForms[i].querySelector(payment_button_class);
if (soldOutBtn) {
break;
} else {
const iptSubArr = trueForms[i].querySelectorAll(
"input[type='submit']"
);
// 如果存在input的类型为submit,则将该按钮数组里第一个直接赋给soldOutBtn,并结束循环
if (iptSubArr.length != 0) {
soldOutBtn = iptSubArr[0];
break;
}
// 如果不存在input的类型为submit,则获取form下的所有按钮进行遍历
const btnArr = trueForms[i].querySelectorAll("button");
for (let j = 0; j < btnArr.length; j++) {
if (btnArr[j].type == "submit") {
// 如果有类型为submit的按钮,直接将该按钮赋给soldOutBtn,并结束循环
soldOutBtn = btnArr[j];
// 注意,这里的break只是中断了当前的循环,外层循环还会继续。
break;
}
}
}
}
// 循环结束
}
if (soldOutBtn || exactForm) {
const params = { code: 0, msg: "success" };
if (soldOutBtn) {
insertType = "afterend";
insertEl = soldOutBtn;
} else {
insertType = "beforeend";
insertEl = exactForm;
}
resolve(params);
} else if (times >= MAX_SEARCH_TIMES) {
resolve({ code: 501, msg: "Search el failed" });
} else {
times++;
setTimeout(() => {
searchParentEl().then((res) => resolve(res));
}, 50);
}
});
}
function getParentWithoutForm() {
// 找所有的有可能是add-to-cart按钮的类名,用循环判断按钮位置
const btnElements =
qa(`.action-button, [class*=add-to-cart], [class*=add_to_cart], [id*=add_to_card],
[id*=add-to-card], [data-add-to-cart], .sold-out, #out-of-stock-gl,.option-selectors`);
if (btnElements.length) {
for (let i = 0; i < btnElements.length; i++) {
// 有的时候增加/减少产品数量的按钮可能也会被选进来,用宽度排除
const width = Number(
window.getComputedStyle(btnElements[i], null).width.split("px")[0]
);
// 如果按钮有宽度,而且宽度>64,则大概率不是
if (!isNaN(width) && width > 64) {
return { type: "afterend", ele: btnElements[i] };
}
}
}
const parents = qa(
".action-button, .tt-swatches-container.tt-swatches-container-js"
);
if (parents.length) {
for (let i = 0; i < parents.length; i++) {
const style = window.getComputedStyle(parents[i], null);
if (
style.visibility != "visible" ||
style.display == "none" ||
style.height == "0px" ||
style.height == "0" ||
style.width == "0px" ||
style.width == "0" ||
style.height == "auto"
) {
continue;
}
return { type: "beforeend", ele: parents[i] };
}
}
return { type: "" };
}
// 如果searchParentEl方法没有找到form
function setInlineBtnWhenErr(el) {
const res = getParentWithoutForm();
res.type && res.ele.insertAdjacentHTML(res.type, el);
getBISEle();
}
function handleSearchNodeFailed() {
return new Promise((resolve) => {
getButtonStyle(shopId, buttonStyleUrl).then(() => {
if (!buttonData.insert_element_selector) {
const newParentData = getParentWithoutForm();
if (!newParentData.type) {
resolve({ code: 404 });
} else {
resolve({ code: 0 });
}
} else {
resolve({ code: 0 });
}
});
});
}
// Mark 按钮自定义位置
function changeButtonPos() {
/**
* 用于更改按钮的位置/searchParentEl失败时指定parent
*/
const {
customize_inline_btn_position,
insert_element_selector,
insert_type,
} = buttonData;
const isBlock = q("#sealapps-bis-widget");
if (isProPage && isBlock) {
insertEl = isBlock;
insertType = "beforeend";
} else {
let selector = null;
let position = null;
if (customize_inline_btn_position === 1) {
selector = insert_element_selector;
position = insert_type;
} else if (Object.keys(u.insert_button_info).length !== 0) {
selector = u.insert_button_info.selector;
position = u.insert_button_info.position;
}
if (selector && position) {
if (isProPage) {
insertEl = q(selector) || soldOutBtn;
} else if (isCollPage) {
insertEls = Array.from(qa(selector));
}
insertType = position || "afterend";
}
}
}
function handleBasicData() {
if (soldOutBtn) {
const parentStyle = window.getComputedStyle(
soldOutBtn.parentElement,
null
);
if (
parentStyle.display == "flex" &&
parentStyle.flexDirection == "row" &&
parentStyle.flexWrap == "nowrap"
) {
soldOutBtn.parentElement.style.flexWrap = "wrap";
}
}
const v1 = variantData[0];
try {
const arr = v1.name.split("-");
if (arr.length === 1) {
productTitle = v1.name;
} else {
if (arr.length === 2 && shopId === 77709705552) {
productTitle = v1.name;
} else {
productTitle = arr.slice(0, -1).join("-");
}
}
productTitle = productTitle.trim();
if (shopId === 61058973863) {
productTitle = v1.name;
} else if (shopId === 55190913133) {
productTitle = v1.name.split("-").slice(0, -1).join("-");
}
} catch (error) {
if (!v1.public_title) {
productTitle = v1.name;
} else {
if (v1.public_title.length - 3 > 0) {
productTitle = v1.name.substr(
0,
v1.name.length - v1.public_title.length - 3
);
} else {
productTitle = v1.name;
}
}
}
}
// ## 获取所有数据
async function getAllData() {
document.head.insertAdjacentHTML(
"beforeend",
''
);
emailStyle = document.querySelector(".email-style");
getPopupStyle(shopId, popupStyleUrl);
getIntegration(shopId, integrationUrl);
// if (isProPage) {
// getButtonStyle(productPageType);
// // requests.buttonSettings(productPageType);
// }
}
function startRender() {
if (getDataCount === 3) {
// 产品页,在嵌入前发现已经嵌入过了,退出
if (isProPage) {
const nodes = qa(`#product-restore-email-float,.product-restore-email`);
if (nodes.length === 0) {
renderBtnAndPopup();
}
} else if (isCollPage) {
renderBtnAndPopup();
}
}
}
//Mark 请求按钮按钮样式接口
async function getButtonStyle(page_type) {
if (btnStyleSwitch) {
getDataCount++;
return new Promise((resolve) => {
resolve({ code: 0 });
});
} // 请求过了就return
let isSuccess = false;
let data = null;
if (
updateStatus.is_button_settings_updating !== 1 &&
((typeof bis_product_button_settings !== "undefined" && isProPage) ||
(typeof bis_collection_button_settings !== "undefined" && isCollPage))
) {
isSuccess = true;
data = bis_product_button_settings;
if (isCollPage) {
data = bis_collection_button_settings;
}
} else {
await requests.buttonSettings(page_type).then((res) => {
if (res.code === 0 && res.data) {
data = res.data;
isSuccess = true;
}
});
}
if (isSuccess) {
btnStyleSwitch = 1;
// inline设置
Object.keys(buttonData).forEach((key) => {
buttonData[key] = data[key];
});
if (q("#sealapps-bis-widget")) {
buttonData.is_active_inline_btn = 1;
}
Object.keys(generalData).forEach((key) => {
generalData[key] = data[key];
});
if (isCollPage) {
generalData.font_family = generalData.font_weight = "inherit";
}
renderSettingStyles();
if (isProPage) {
changeButtonPos();
}
getDataCount++;
startRender();
}
}
//Mark 请求弹窗样式接口
async function getPopupStyle(shopId, popupUrl) {
// API路由
let isSuccess = false;
if (
updateStatus.is_popup_settings_updating !== 1 &&
typeof bis_popup_settings !== "undefined"
) {
popupStyleSwitch = 1;
popupData = bis_popup_settings;
isSuccess = true;
} else {
const res = await requests.popupSettings();
const { code, data } = res;
if (code === 0 && data) {
isSuccess = true;
popupStyleSwitch = 1;
popupData = JSON.parse(JSON.stringify(data));
}
}
if (isSuccess) {
switch (popupData.popup_template) {
case 1:
selectedType.type = "email";
break;
case 2:
selectedType.type = "sms";
break;
case 3:
selectedType.type = "email";
break;
}
getDataCount++;
startRender();
}
}
//Mark 请求集成情况接口
function getIntegration(shopId, inteUrl) {
// API路由
if (
updateStatus.is_integrations_updating !== 1 &&
typeof bis_integrations !== "undefined"
) {
inteStatus = bis_integrations.find((o) => o.is_enable === 1);
getDataCount++;
startRender();
} else {
return requests.integrationStatus().then((res) => {
const { code, data } = res;
if (code === 0 && data) {
// 只要有开启了的选项,就打开集成
inteStatus = data.list.find((o) => o.is_enable === 1);
getDataCount++;
startRender();
} else {
getDataCount++;
startRender();
}
});
}
}
function renderSettingStyles() {
const {
font_size,
horizontal_animation,
border_radius,
border_color,
font_weight,
font_family,
inline_btn_margin_top,
inline_btn_margin_bottom,
hover_text_color,
hover_bg_color,
customize_css,
} = generalData;
let generalStyles = `
.email-me-button {
font-size: ${font_size}px !important;
font-weight: ${font_weight} !important;
font-family: ${font_family} !important;
border-color: ${border_color} !important;
border-radius: ${border_radius}px !important;
border-width: 2px;
border-style: solid;
}
.email-me-button.email-me-submitButton {
height:auto;
min-height: 46px;
}
.email-me-button:hover {
color: ${hover_text_color} !important;
background-color: ${hover_bg_color} !important;
}
${customize_css}
`;
if (horizontal_animation) {
generalStyles += `
.email-me-inlineButton::after,
.email-me-inlineButton::before,
.email-me-submitButton::after,
.email-me-submitButton::before {
content:'';
color: ${buttonData.inline_btn_bg_color};
font-size: ${font_size}px;
text-align: center;
border-radius: ${border_radius}px;
width: 0;
height: 100%;
background-color: ${hover_bg_color};
position: absolute;
left:0;
transition: all ease-in-out .35s;
top:0;
z-index: -2;
}
.email-me-inlineButton::before,
.email-me-submitButton::before {
z-index: -1;
background-color: ${hover_bg_color};
}
.email-me-inlineButton:hover,
.email-me-submitButton:hover {
z-index: 1;
color: ${hover_text_color} !important;
background-color: ${hover_bg_color} !important;
}
.email-me-button:hover::before,
.email-me-button:hover::after
{
width: 100%;
}
`;
}
const styles = `
`;
document.head.insertAdjacentHTML("beforeend", styles);
}
// Mark 渲染弹窗
function renderBtnAndPopup() {
// 预先创建没有库存的variantOptions
const { toggler, ipt, mailingList } = renderSpecificPopup();
const mountWindowElement = `
${popupData.success_content}
${productTitle}
${toggler || ""}
${ipt}
${mailingList || ""}
${
popupData.is_branding_removed
? ""
: `
`
}
`;
document.body.insertAdjacentHTML("beforeend", mountWindowElement);
const n = document.querySelector("#sealapps-bis-widget");
if (n && soldOutBtn) {
if (getComputedStyle(soldOutBtn.parentNode).textAlign === "center") {
emailStyle.textContent +=
"#sealapps-bis-widget{justify-content:center}";
}
}
renderButton().then((res) => {
if (res.code === 0) {
// 渲染按钮成功,进行下一步的操作
// changeButtonPos();
getBISEle(); // 获取所有需要进行操作的DOM元素
createEmailButton(); // 查询店铺是否开启按钮
listenVariantChange(); // 开始监听变体的变化
// 运行前执行用户需求自定义函数
if (typeof bisAfterExecute !== "undefined") {
bisAfterExecute(v);
}
if (popupData.popup_template !== 1) {
initSms(); // 初始化短信相关的操作
}
} else {
}
});
}
// Mark 渲染按钮
function renderButton() {
// 根据开启类型渲染按钮
return new Promise((resolve, reject) => {
const { is_active_inline_btn, is_active_float_btn } = buttonData;
let flag = 0;
if (is_active_inline_btn || isCollPage) {
// 如果开启了inline,挂载inline
const {
inline_text_color,
inline_btn_bg_color,
inline_btn_text,
collection_btn_value,
inline_btn_margin_top,
inline_btn_margin_bottom,
} = buttonData;
let btnText = inline_btn_text;
const mountInlineBtn = `
`;
if (isProPage) {
try {
console.log("insertEl", insertEl);
insertEl.insertAdjacentHTML(insertType, mountInlineBtn);
flag++;
} catch (err) {
setInlineBtnWhenErr(mountInlineBtn);
flag++;
}
} else if (isCollPage) {
insertEls.forEach((i, inx) => {
iparentNode = i.parentNode;
const isHaveBtn = qa(".product-restore-email", iparentNode);
if (isHaveBtn.length == 0) {
const wrapper = document.createElement("div");
wrapper.setAttribute("proId", collVariants[inx].proId);
wrapper.innerHTML = mountInlineBtn;
wrapper.style.position = "relative";
wrapper.style.zIndex = "1";
wrapper.className = "restore-email-wrapper";
i.insertAdjacentElement(insertType, wrapper);
i.setAttribute("bis-inserted", true);
}
});
flag++;
}
}
if (is_active_float_btn) {
const {
float_offset,
float_text_color,
float_btn_bg_color,
float_btn_text,
} = buttonData;
const mountFloatBtn = `
`;
document.body.insertAdjacentHTML("afterbegin", mountFloatBtn);
flag++;
}
if (flag > 0) {
resolve({ code: 0, msg: "Success!" });
} else {
resolve({ code: 404, msg: "Insert failed" });
}
});
}
function renderSpecificPopup() {
inlineBtnElement;
/*
* 根据用户开启的弹窗类型进行部分渲染
* 1 - 只开了邮件,渲染邮件输入框
* 2 - 只开了短信,渲染sms输入框
* 3 - 都开了,渲染两种输入框以及toggler(开关)
*/
let ipt, toggler, mailingList;
console.log("popupData", popupData);
type = popupData.popup_template;
if (type === 1) {
ipt = `
`;
} else if (type === 2) {
ipt = `
`;
} else if (type === 3) {
ipt = `
`;
const email = `
${popupData.email_tab_text}
`;
const sms = `
${popupData.sms_tab_text}
`;
let content = "";
if (shopId === 56661573841) {
content = sms + email;
} else {
content = email + sms;
}
toggler = `
${content}
`;
}
renderSpecificStyle(type);
if (inteStatus) {
mailingList = `
`;
}
return {
ipt,
toggler,
mailingList,
};
}
function renderSpecificStyle(type) {
switch (type) {
case 1:
case 2:
addStyle(
``
);
break;
case 3:
addStyle(
``
);
break;
default:
break;
}
}
//Mark 获取Back in stock相关的元素
function getBISEle() {
switch (popupData.popup_template) {
case 1:
emailInput = q(".buyer-email");
break;
case 2:
smsInput = q(".buyer-phone");
break;
case 3:
emailInput = q(".buyer-email");
smsInput = q(".buyer-phone");
break;
}
nameInput = q(".email-frame-body .buyer-name");
successFrame = q(".successSub");
invalidTip = q(".invalid-email-tips");
emailFrameElement = q("#email-me-frame");
closeBox = q("#email-me-frame .close-box");
submitBtn = q(".frame-submit .email-me-button");
variantSelector = q(".selected-unavailable-variant");
inlineEmailDiv = qa(".product-restore-email");
floatEmailDiv = q("#product-restore-email-float");
inlineBtnElement = qa(".email-me-inlineButton");
floatBtnElement = q(".email-me-floatButton");
mailingCheckbox = q("#join-mailing-list") || {};
insertStyle = q("#email-insert-style");
// 获取完了各个元素之后开始进行事件的添加
handleEleEvent();
}
// Mark 控件添加事件
function handleEleEvent() {
// 对各个元素进行事件处理与绑定
switch (popupData.popup_template) {
case 1:
emailInput.addEventListener("blur", verifyEmail);
break;
case 2:
break;
case 3:
emailInput.addEventListener("blur", verifyEmail);
break;
}
submitBtn.addEventListener("click", subEmail);
// submitBtn.addEventListener('click', debounce(500, subEmail));
closeBox.addEventListener("click", function () {
emailFrameElement.style.display = "none";
if (variantSelector.style.display !== "none") {
currentVariantOption &&
currentVariantOption.removeAttribute("selected");
}
});
successFrame.addEventListener("click", function () {
successFrame.classList.remove("successSub_active");
});
if (isProPage) {
mountedUnVariantOptions();
}
initInlineAndFloatBtn();
}
// Mark 添加按钮事件
function initInlineAndFloatBtn() {
if (inlineBtnElement.length) {
inlineBtnElement.forEach((i, inx) => {
i.addEventListener("click", function (e) {
e.preventDefault();
autoInput();
let curProId = 0;
emailFrameElement.style.display = "block";
const selected_unavailable_variant = emailFrameElement.querySelector(
".selected-unavailable-variant"
);
if (isCollPage) {
curProId = this.parentNode.parentNode.getAttribute("proId");
let oldProId = selected_unavailable_variant.getAttribute("proId");
if (oldProId) {
if (oldProId !== curProId) {
addOptionsStatus = 0;
variantData = collVariants.find(
(i) => i.proId == curProId
).variants;
unVariantOptions = [];
mountedUnVariantOptions();
selected_unavailable_variant.innerHTML = "";
selected_unavailable_variant.setAttribute("proId", curProId);
}
} else {
unVariantOptions = [];
variantData = collVariants.find(
(i) => i.proId == curProId
).variants;
mountedUnVariantOptions();
selected_unavailable_variant.setAttribute("proId", curProId);
}
}
// 挂载没有库存的variant option
for (let i = 0; i < unVariantOptions.length; i++) {
if (addOptionsStatus === 0) {
selected_unavailable_variant.add(unVariantOptions[i]);
}
if (
unVariantOptions[i].getAttribute("value") ===
selectVariantId.toString()
) {
currentVariantOption =
selected_unavailable_variant.querySelectorAll("option")[i];
currentVariantOption.setAttribute("selected", "selected");
}
}
addOptionsStatus = 1;
});
});
// inlineBtnElement.addEventListener('click', function () {
// autoInput();
// emailFrameElement.style.display = 'block';
// // 挂载没有库存的variant option
// const selected_unavailable_variant = emailFrameElement.querySelector('.selected-unavailable-variant');
// for (let i = 0; i < unVariantOptions.length; i++) {
// if (addOptionsStatus === 0) {
// selected_unavailable_variant.add(unVariantOptions[i]);
// }
// if (unVariantOptions[i].getAttribute('value') === selectVariantId.toString()) {
// currentVariantOption = selected_unavailable_variant.querySelectorAll('option')[i];
// currentVariantOption.setAttribute('selected', 'selected');
// }
// }
// addOptionsStatus = 1;
// });
}
if (floatBtnElement) {
floatBtnElement.addEventListener("click", function () {
autoInput();
emailFrameElement.style.display = "block";
// 挂载没有库存的variant option
// const selected_unavailable_variant = emailFrameElement.querySelector('.selected-unavailable-variant');
for (let i = 0; i < unVariantOptions.length; i++) {
if (addOptionsStatus === 0) {
variantSelector.add(unVariantOptions[i]);
}
if (
unVariantOptions[i].getAttribute("value") ===
selectVariantId.toString()
) {
currentVariantOption =
variantSelector.querySelectorAll("option")[i];
currentVariantOption.setAttribute("selected", "selected");
}
}
addOptionsStatus = 1;
});
}
}
// 自动填入登录用户的信息
function autoInput() {
if (JSON.stringify(customerInfo) != "{}") {
nameInput.value = customerInfo.name;
if (emailInput) {
emailInput.value = customerInfo.email;
}
if (smsInput) {
smsInput.value = customerInfo.phone.replace(/[^0-9]/g, "");
}
}
}
// Mark 生成弹窗变体下拉框选项
function mountedUnVariantOptions() {
let optionIndex = 0;
let title,
id = "id";
if (isProPage) {
title = "title";
} else if (isCollPage) {
title = "title";
id = "variant_id";
}
if (isCollPage) {
setProName(variantData[0].product_id);
}
if (variantData.length === 1 && variantData[0].title === "Default Title") {
variantSelector.style.display = "none";
} else {
variantSelector.style.display = "block";
}
for (let i = 0; i < variantData.length; i++) {
// 如果variantData存在此变体id则该变体需要展示按钮
if (
(showVariants.includes(String(variantData[i].id)) && isProPage) ||
isCollPage
) {
unVariantOptions[optionIndex] = create({
tag: "option",
attributes: {
value: variantData[i][id],
textContent: variantData[i][title],
},
});
optionIndex++;
}
}
}
//Mark 防抖监听集合页元素变动
async function collPageObserve() {
observer.disconnect();
const curEls = await getProsEle();
const bns = qa(".product-restore-email").length;
if ((curEls !== null && curEls.length !== oldCollElsCount) || !bns) {
// collVariants = [];
insertEls = [];
selBtnStatus = 0;
getDataCount = 0;
await init();
execute();
} else {
checkVariantChange();
}
}
// Mark 监听变体切换
function listenVariantChange() {
/**
* 该方法主要用于判断使用什么方法监听变体的变化
* 1. 当url中包含variant=的时候,采用listen url的方法
* 2. 当url中不包含的时候,采用定时器的方法
*/
if (isProPage) {
const url = document.URL;
listenUrlStatus();
if (
url.indexOf("variant=") === -1 ||
shopId == 1742274613 ||
shopId == 50606899391 ||
shopId === 72936030549
) {
checkVariantChange();
}
} else if (isCollPage) {
setTimeout(() => {
checkVariantChange();
}, 1000);
}
}
//Mark 当观察到变动时执行的回调函数
function setCollDeb() {
observerCallback = debounce(400, function () {
if (isProPage) {
let curVariantId;
if (shopId == 55013703857) {
const selectedTitle = q(".select-selected").innerText;
curVariantId = variantData.find((o) => o.title == selectedTitle).id;
} else if (shopId == 1742274613) {
const option1Node = q(".option-0");
const option2Node = q(".option-1");
const option1Title =
option1Node.querySelector(".selected_val").innerText;
const option2Title =
option2Node.querySelector(".selected_val").innerText;
curVariantId = variantData.find(
(o) => o.option1 == option1Title && o.option2 == option2Title
).id;
} else if (shopId === 56342347836) {
const ns = q(".t4s-product__select.t4s-d-none");
curVariantId = ns.value;
} else if (shopId === 72936030549) {
curVariantId = variantData.find(
(it) => it.title === q(".swatch input:checked").value
).id;
} else {
curVariantId = q("input[name=id], select[name=id]").value;
}
handleVariantChange(curVariantId);
} else if (isCollPage) {
collPageObserve();
}
});
}
// Mark 产品页变体切换监听
function checkVariantChange() {
// 选择要观察变动的节点
let targetNode;
if (isProPage) {
if (shopId == 55013703857) {
targetNode = q(".select-selected, select[name=id]");
} else if (shopId == 1742274613) {
targetNode = q(".option-1");
} else if (shopId == 42547151016 && themeId === 122478428328) {
targetNode = q(".swatch-variants-wrapper");
} else if (shopId == 57593233596 && themeId === 132009820348) {
targetNode = q(".swatches-select.swatch__list_pr");
} else if (shopId == 16708787 && themeId === 141528334609) {
targetNode = q(".shopify-product-form");
} else if (shopId == 56342347836 && themeId === 160444678479) {
targetNode = q("form .t4s-swatch");
} else if (shopId == 23566876752 && themeId === 122101039184) {
targetNode = q(".swatches-select");
} else if (shopId == 63893045484 && themeId === 136267792620) {
targetNode = q(".option-selectors");
} else if (shopId == 55224107147 && themeId === 123578253451) {
targetNode = q(".product-select-simple-wrapper");
} else if (shopId == 50606899391 && themeId === 147023823194) {
targetNode = q(".ProductForm__Variants");
} else {
switch (shopId) {
case 78542635323: {
if (themeId === 158288609595) {
targetNode = q(".t4s-swatch__list");
}
break;
}
case 72936030549: {
if (themeId === 147312345429) {
targetNode = q(".maxus-productdetail__options");
}
break;
}
default: {
if (v.variantListenerElement) {
targetNode = q(v.variantListenerElement);
} else {
targetNode = q("input[name=id], select[name=id]");
}
}
}
}
if (!targetNode) {
targetNode = q("input[name=id], select[name=id]");
}
} else if (isCollPage) {
targetNode = q("main");
if (shopId === 25981404 && themeId === 132868636834) {
targetNode = q("#main");
}
}
if (targetNode) {
// 观察器的配置l
const config = { attributes: true, childList: true, subtree: true };
// 创建一个观察器实例并传入回调函数
observer = new MutationObserver(observerCallback);
// 以上述配置开始观察目标节点
observer.observe(targetNode, config);
}
}
function listenUrlStatus() {
overwritePushstate();
window.addEventListener("locationchange", () => {
const currentUrl = document.URL;
// 如果之后开始要对collection页展示按钮了,可能会用到下面两行
// const url = new URL(currentUrl);
// const isVariantUrl = url.searchParams.get('variant');
if (currentUrl !== initUrl) {
const currentUrl = document.URL;
const url = new URL(currentUrl);
const vid = url.searchParams.get("variant");
initUrl = currentUrl;
vid && handleVariantChange(vid);
listenVariantFlag = false;
}
});
}
function handleVariantChange(vid) {
/**
* TODO 当切换变体后url中开始有variant=了
* 取消listen变体的定时器
*/
if (!vid) return;
if (String(selectVariantId) !== String(vid)) {
selectVariantId = vid;
currentVariant = variantData.find((o) => o.id == vid);
available = currentVariant.available;
if (
(showVariants.includes(String(selectVariantId)) && !btnStyleSwitch) ||
!popupStyleSwitch
) {
getAllData();
}
if (showVariants.includes(String(selectVariantId)) && !selBtnStatus) {
createEmailButton();
}
if (selBtnStatus === 1) {
initEmailToMeElement();
}
}
}
//Mark 查询店铺订阅按钮的状态
async function createEmailButton() {
if (selBtnStatus === 0) {
// 还未成功请求服务器
// url后缀
let isSuccess = false;
let data = null;
if (
updateStatus.button_status === 2 &&
typeof bis_button_status !== "undefined"
) {
isSuccess = true;
data = bis_button_status;
} else {
// const url = baseUrl + "api/v1/email/selBtnStatus";
// await request(url, { shopId }).then((res) => {
// if (res.code === 0) {
// isSuccess = true;
// data = res.data;
// }
// });
isSuccess = true;
data = { status: 1 };
}
if (isSuccess) {
if (
data.status == 1 ||
data.status == 2 ||
data.status == 0 ||
data.snsStatus
) {
selBtnStatus = 1;
initEmailToMeElement();
} else {
selBtnStatus = data.status;
}
}
}
}
//Mark 初始化按钮
function initEmailToMeElement() {
// 移除了displayforall的判断,统一由后端判断该变体需不需要展示
if (generalData.display_all === 1) {
if (inlineBtnElement) {
inlineBtnElement.forEach((i) => (i.style.display = "flex"));
inlineEmailDiv.forEach((i) => (i.style.display = "flex"));
}
if (floatBtnElement) {
floatBtnElement.style.display = "flex";
floatEmailDiv.style.display = "flex";
}
return;
}
if (
selBtnStatus === 1 &&
((showVariants.includes(String(selectVariantId)) && isProPage) ||
isCollPage)
) {
customFeature && customFeature();
if (inlineBtnElement) {
inlineBtnElement.forEach((i) => (i.style.display = "flex"));
inlineEmailDiv.forEach((i) => (i.style.display = "flex"));
}
if (floatBtnElement) {
floatBtnElement.style.display = "flex";
floatEmailDiv.style.display = "flex";
}
} else {
if (inlineBtnElement) {
// inlineBtnElement.style.display = "none";
inlineEmailDiv.forEach((i) => {
i.style.display = "none";
});
}
if (floatBtnElement) {
// floatBtnElement.style.display = 'none';
floatEmailDiv.style.display = "none";
}
}
}
//Mark 校验邮件格式
function verifyEmail() {
const email = emailInput.value;
const reg = new RegExp(
/^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,}$/
);
if (!reg.test(email)) {
toggleInvalidTip(true, {
type: "email",
info: popupData.verification_failed_text,
});
} else {
invalidTip.style.visibility = "hidden";
}
}
//Mark 创建element
function create({
tag,
appendTo,
children = [],
attributes = {},
events = {},
}) {
const element = document.createElement(tag);
Object.entries(attributes).forEach(([key, value]) => {
element[key] = value;
});
Object.entries(events).forEach(([key, value]) => {
element.addEventListener(key, value);
});
if (appendTo) {
appendTo.appendChild(element);
}
children.forEach((child) => element.appendChild(child));
return element;
}
//Mark 提交订阅 selectVariantId
function subEmail() {
console.log("subEmail");
const { verification_failed_text } = popupData;
let buyerName;
if (nameInput) {
buyerName = nameInput.value;
}
console.log("selectedType.type", selectedType.type);
switch (selectedType.type) {
case "sms":
const sms = (smsInput && smsInput.value) || "";
if (!sms) {
toggleInvalidTip(true, {
type: "sms",
info: verification_failed_text,
});
} else {
if (iti.isValidNumber()) {
toggleInvalidTip(false);
subscribeSms({ buyerName });
} else {
toggleInvalidTip(true, {
type: "sms",
info: verification_failed_text,
});
}
}
break;
case "email":
const email = emailInput.value;
console.log("email", email);
if (!email) {
console.log(5555);
toggleInvalidTip(true, {
type: "email",
info: verification_failed_text,
});
} else {
// 判断邮件的格式是否正确
const reg = new RegExp(
/^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,}$/
);
if (reg.test(email)) {
toggleInvalidTip(false);
subscribeEmail({ buyerName });
} else {
toggleInvalidTip(true, {
type: "email",
info: verification_failed_text,
});
}
}
break;
default:
return;
}
}
function toggleInvalidTip(show, data) {
/**
* 函数的本意是为了开关invalid提示,但是如果设置了show的话就是为了手动隐藏/关闭
* show - 展示/隐藏提示
* data.type - 当前提示的类型
* data.info - 当前提示的信息
*/
const style = getComputedStyle(invalidTip);
const { type, info } = data || {
type: selectedType.type,
info: popupData.verification_failed_text,
};
switch (type) {
case "sms":
invalidTip.innerHTML = info;
if (style.visibility === "hidden") {
invalidTip.style.visibility = "visible";
} else {
invalidTip.style.visibility = "hidden";
}
break;
case "email":
invalidTip.innerHTML = info;
if (style.visibility === "hidden") {
invalidTip.style.visibility = "visible";
} else {
invalidTip.style.visibility = "hidden";
}
break;
default:
invalidTip.style.visibility = "hidden";
break;
}
if (show) {
invalidTip.style.visibility = "visible";
} else if (show === false) {
invalidTip.style.visibility = "hidden";
}
}
// Mark 发送短信
function subscribeSms(data) {
// 传递的参数
const params = {
shopId: shopId,
phone: formatPhoneNumber(smsInput.value.trim()),
phone_region: iti.getSelectedCountryData().iso2.toUpperCase(),
is_integration: Number(mailingCheckbox.checked || false),
variant_id: variantSelector.value,
subscriber_name: data.buyerName || "customer",
lang: locale,
};
const url = bisBaseUrl + "api/v1/product/add_customer_stock_subscription";
submitBtn.parentElement.className = "frame-submit loading";
request(url, params)
.then((res) => {
const { code, message } = res;
if (code === 0) {
emailFrameElement.style.display = "none";
successFrame.classList.add("successSub_active");
setTimeout(function () {
successFrame.classList.remove("successSub_active");
}, 4000);
} else if (code === 6 || code === 10) {
// 新增订阅失败
invalidTip.style.visibility = "visible";
invalidTip.innerHTML = popupData.subscribed_text;
} else if (code === 3) {
invalidTip.style.visibility = "visible";
invalidTip.innerHTML = popupData.verification_failed_text;
} else {
invalidTip.style.visibility = "visible";
invalidTip.innerHTML = message;
}
})
.finally(() => {
submitBtn.parentElement.className = "frame-submit";
});
}
// Mark 订阅邮件
function subscribeEmail(data) {
// url后缀
// 传递的参数
const params = {
variant_id: variantSelector.value,
email: document.getElementsByClassName("buyer-email")[0].value,
subscriber_name: data.buyerName || "customer",
is_integration: Number(mailingCheckbox.checked || false),
langg: locale,
};
const url = bisBaseUrl + "api/v1/product/add_customer_stock_subscription";
submitBtn.parentElement.className = "frame-submit loading";
request(url, params)
.then((res) => {
const { code, message } = res;
if (code === 0) {
emailFrameElement.style.display = "none";
successFrame.classList.add("successSub_active");
setTimeout(function () {
successFrame.classList.remove("successSub_active");
}, 4000);
} else if (code === 6 || code === 10) {
// 新增订阅失败
invalidTip.style.visibility = "visible";
invalidTip.innerHTML = popupData.subscribed_text;
} else if (code === 3) {
invalidTip.style.visibility = "visible";
invalidTip.innerHTML = popupData.verification_failed_text;
} else {
invalidTip.style.visibility = "visible";
invalidTip.innerHTML = message;
}
})
.finally(() => {
submitBtn.parentElement.className = "frame-submit";
});
}
function formatPhoneNumber(num) {
const code = iti.getSelectedCountryData().dialCode;
//把开头为0的过滤
num = num.replace(/\b(0+)/gi, "");
if (!num.startsWith(code)) {
// 如果电话不是以区号开头的,直接拼接区号并返回
return code + num;
} else {
return num;
}
}
function initSms() {
const emailInput = q(".buyer-email");
// const phoneInput = q('.buyer-phone-block');
const phoneInput = q(".buyer-phone");
const phoneContainer = q(".buyer-phone-container");
// const countrySelector = q('.country-selector');
// const countryList = q('.country-selector-list');
const emailTypeBtn = q(".email-type");
const smsTypeBtn = q(".sms-type");
const regionFlag = q(".iti--allow-dropdown");
if (!regionFlag) {
initPhoneInput().then((res) => {
if (res.code === 0 && popupData.popup_template === 3) {
selectedType = new Proxy(
{ type: "email" },
{
set(target, key, newVal) {
target[key] = newVal;
toggleInput(newVal);
return true;
},
}
);
toggleInput(selectedType.type);
emailTypeBtn.addEventListener("click", () => {
selectedType.type = "email";
});
smsTypeBtn.addEventListener("click", () => {
selectedType.type = "sms";
});
}
});
}
function initPhoneInput() {
/*
* 在这里引入了插件intl-tel-input
* 具体的使用方法可以在这两个地方看
* npm: https://www.npmjs.com/package/intl-tel-inpu
* github: https://github.com/jackocnr/intl-tel-input#getting-started-not-using-a-bundler
* 在这里有对应的全套cdn https://cdnjs.com/libraries/intl-tel-input
*/
return new Promise((resolve) => {
const cssUrl =
"https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.16/css/intlTelInput.css";
addScript(cssUrl).then((cssRes) => {
if (cssRes.code === 0) {
// 国旗是png格式的精灵图,也是由cdn引入的,具体看下面resetFlag中的参数
const resetFlag = `
`;
document.head.insertAdjacentHTML("beforeend", resetFlag);
// 确保插件的css引入了之后再进行js的引入
addScript(
"https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.16/js/intlTelInput.min.js",
true
).then((script) => {
// 获得创建的script元素,再将script元素引入之前先对其进行
script.onload = function () {
iti = window.intlTelInput(phoneInput, {
utilsScript:
"https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.16/js/utils.min.js",
autoPlaceholder: "aggressive",
initialCountry: popupData.sms_default_region || "",
});
phoneInput.addEventListener("input", (e) => {
iti.isValidNumber()
? toggleInvalidTip(false)
: toggleInvalidTip(true);
});
phoneInput.addEventListener("blur", (e) => {
iti.isValidNumber()
? toggleInvalidTip(false)
: toggleInvalidTip(true);
});
};
document.body.appendChild(script);
resolve({ code: 0 });
});
}
});
});
}
function toggleInput(type) {
// 切换Email / SMS选项时进行操作
invalidTip.style.visibility = "hidden";
switch (type) {
case "sms":
emailInput.style.display = "none";
phoneContainer.style.display = "flex";
emailTypeBtn.className = "email-type";
smsTypeBtn.className = "sms-type type-selected";
// mailingCheckbox.parentElement.style.display = 'none';
break;
case "email":
smsTypeBtn.className = "sms-type";
emailInput.style.display = "block";
phoneContainer.style.display = "none";
emailTypeBtn.className = "email-type type-selected";
// mailingCheckbox.parentElement.style.display = 'flex';
break;
default:
invalidTip.style.visibility = "hidden";
break;
}
}
}
// 封装引入js, css的函数
function addScript(url, returnWithScript = false) {
return new Promise((resolve, reject) => {
try {
const type = (url.endsWith(".js") && "js") || "css";
if (type === "js") {
const script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", url);
if (returnWithScript) {
resolve(script);
}
document.head.appendChild(script);
resolve({ code: 0, data: script, type: "script" });
} else if (type === "css") {
const link = document.createElement("link");
link.setAttribute("rel", "stylesheet");
link.setAttribute("href", url);
if (returnWithScript) {
resolve(link);
}
document.head.appendChild(link);
resolve({ code: 0, data: link, type: "style" });
}
} catch (err) {
reject({ code: 600, err });
}
});
}
/**
* @function createRequestId 创建RequestId用于链路追踪
* @param {integer} length 希望生成的字符串长度
* @returns {string} 指定长度的字符串
*/
function createRequestId(length) {
// length边界处理
length = length && length < 64 ? length : 63;
let result = "";
const chars =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
for (let i = 0; i < length; ++i) {
result += chars[Math.floor(Math.random() * chars.length)];
}
const timestamp = +new Date();
return result + timestamp;
}
function request(url, params, method = "POST", callback) {
/**
* 封装请求函数
* @param(url) - api请求地址,必选。
* @param(params) - 请求参数,可选。
* @param(callback) - 回调函数,可选。没有回调函数也会resolve获得到的数据
* @param(method) - 请求方法,可选。
* @returns Promise
*/
return new Promise((resolve, reject) => {
if (!url) {
resolve({ code: 999, data: "没有传api地址" });
}
try {
// 有params就拆params,不然就给个空对象方便请求
const finalParams = params || {};
if ((params && !Object.keys(params).includes("shopId")) || !params) {
finalParams.shop_id = shopId; // 参数中没给shopId就给一下
}
const xmlHttp = new XMLHttpRequest();
if (method === "GET") {
url += objectToQuery(params);
}
// post请求方式
xmlHttp.open(method, url, true);
if (method === "POST") {
// 添加http头,发送信息至服务器时的内容编码类型
xmlHttp.setRequestHeader("Content-Type", "application/json");
if (url.includes("emailnoticeapi")) {
xmlHttp.setRequestHeader("authorization", domain);
// 头部新增 request id 链路追踪
xmlHttp.setRequestHeader("Org-Request-ID", createRequestId(37));
// 头部新增 请求页面
xmlHttp.setRequestHeader("Org-Request-URL", window.location.href);
}
}
xmlHttp.send(method === "POST" ? JSON.stringify(finalParams) : null);
// 发送数据
xmlHttp.onreadystatechange = function () {
// 请求完成
if (
(xmlHttp.readyState == 4 && xmlHttp.status == 200) ||
xmlHttp.status == 304
) {
// 从服务器上获取数据
const json = JSON.parse(this.responseText);
const { code, data } = json;
if (code === 0) {
if (callback) {
callback(data);
}
resolve(json);
} else if (code !== 500) {
resolve(json);
}
}
};
} catch (err) {
reject(err);
}
});
}
async function getUserNeedData() {
//Mark 获取用户需求数据
if (isCollPage || isProPage) {
let needData, needErr;
if (typeof bis_custom_info !== "undefined") {
needData = bis_custom_info;
needErr = null;
}
if (needErr === null) {
// 移动评论区信息
for (let k in needData) {
const list = needData[k];
const len = list.length;
if (len !== 0) {
for (let i = 0; i < list.length; i++) {
const item = list[i];
const tp = item.page || item.target_page;
const tid = item.theme_id;
if (tp) {
if (tp.indexOf(pageType) === -1 && tp !== "all") {
continue;
}
}
if (tid && themeId != tid) {
continue;
}
if (Object.keys(u[k]).length !== 0) {
u[k] = item;
} else if (Object.keys(u[k]).length === 0) {
u[k] = item;
}
}
}
}
}
}
}
// Mark获取需要展示按钮的商品
async function getProductStatus(baseApiUrl) {
let productIds = [];
if (window.ShopifyAnalytics && ShopifyAnalytics.meta.product) {
const productId = ShopifyAnalytics.meta.product.id;
productIds.push(productId);
} else {
return;
}
const params = {
shopId,
product_ids: productIds,
type: 2,
};
const url = baseApiUrl + "api/v1/customer/getVariantBtStatus";
await request(url, params).then((res) => {
const { apiCode, products } = res;
if (apicode === 0 && products) {
//由于是产品页,所以产品肯定只有一个
showVariants = products[0].variants.map((variant) => {
return variant.variant_id;
});
}
});
}
// inject css 样式
function importStyles() {
const styles = ``;
document.head.insertAdjacentHTML("beforeend", styles);
document.head.insertAdjacentHTML(
"beforeend",
``
);
}
function addStyle(style) {
if (typeof style === "string") {
document.head.insertAdjacentHTML("beforeend", style);
} else {
document.head.appendChild(style);
}
}
// 获取url参数
function getQueryString(name) {
const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
const r = window.location.search.substr(1).match(reg);
if (r != null) {
return unescape(r[2]);
}
return null;
}
function changeStatus(data) {
const emailCustomerId = getQueryString("emailCustomerId");
if (!emailCustomerId) {
return;
}
const variantId = getQueryString("variant");
if (!variantId) {
return;
}
const { baseUrl } = data;
// 传递的参数
const params = {
id: emailCustomerId,
shopId,
variantId,
};
// API路由
const url = baseUrl + "api/v1/email/changeEmailStatus";
request(url, params);
}
function overwritePushstate() {
const oldPushState = history.pushState;
history.pushState = function pushState() {
const ret = oldPushState.apply(this, arguments);
window.dispatchEvent(new Event("pushstate"));
window.dispatchEvent(new Event("locationchange"));
return ret;
};
const oldReplaceState = history.replaceState;
history.replaceState = function replaceState() {
const ret = oldReplaceState.apply(this, arguments);
window.dispatchEvent(new Event("replacestate"));
window.dispatchEvent(new Event("locationchange"));
return ret;
};
window.addEventListener("popstate", () => {
window.dispatchEvent(new Event("locationchange"));
});
}
function q(selector, context) {
let node;
if (context) {
node = context.querySelector(selector);
} else {
node = document.querySelector(selector);
}
return node;
}
function qa(selector, context) {
let nodes;
if (context) {
nodes = context.querySelectorAll(selector);
} else {
nodes = document.querySelectorAll(selector);
}
return nodes;
}
function shopLanguageCallback() {
const languageSelector = q(".notranslate");
const languageEl = languageSelector.querySelector(".selected img[alt]");
locale = languageEl.alt;
}
function setProName(curProId) {
productTitle = collVariants.find((i) => i.proId == curProId).productName;
const productTitleEl = q(".frame-body-content");
productTitleEl.innerText = productTitle;
}
/**
* 将对象转换为 URL 查询字符串
* @param {Record} obj - 要转换的对象
* @returns {string} 转换后的查询字符串
* @example
* const params = {
* name: 'John',
* age: 25,
* tags: ['developer', 'js']
* };
* const query = objectToQuery(params);
* // 输出: name=John&age=25&tags=developer&tags=js
*/
function objectToQuery(obj) {
const params = new URLSearchParams();
for (const [key, value] of Object.entries(obj)) {
// 如果是数组,需要特殊处理
if (Array.isArray(value)) {
value.forEach((item) => params.append(key, item));
} else if (value !== null && value !== undefined) {
params.append(key, value.toString());
}
}
return "?" + params.toString();
}
// Mark 用户需求
function addCustomModify() {
switch (shopId) {
case 55605198922: {
customStyle += `#email-me-frame .frame-title, #email-me-frame input {
font-family: 'Sabon Next';
}`;
break;
}
case 66366374137: {
if (isCollPage) {
if (isMobile) {
customStyle += `@media only screen and (min-width: 280px) and (max-width: 757px) {
.product-restore-email{
max-width: initial !important;
}
.email-me-inlineButton{line-height: calc(1 + .2 / var(--font-body-scale));height:auto !important;padding: 6px;}}`;
}
customStyle += `.quick-add__submit[disabled] {
display: none;
}.email-me-inlineButton{min-height: calc(4.5rem + var(--buttons-border-width) * 2);}`;
}
break;
}
case 27251892: {
if (isCollPage) {
customStyle += `.email-me-button.email-me-inlineButton {
width: calc(100% - 100px);
margin: 0 auto;
top: 5px;
}`;
}
break;
}
case 2797404227: {
if (isCollPage) {
customStyle += `#product-grid .grid__item:has(.price-item--sale) {
margin-bottom: 25px;
}`;
}
break;
}
case 31035482: {
if (isCollPage) {
executeDelay = 1000;
customStyle += `#shopify-section-collection-template .collection-products-wrapper {
margin-bottom: 60px;
}@media only screen and (min-width: 768px){.restore-email-wrapper {
top: -15px;
padding: 0 15px;
}}`;
}
break;
}
case 66697953568: {
if (isProPage) {
customFeature = function () {
const n = document.querySelector(
".product_payments_btns .shopify-payment-button__button[disabled]"
);
if (n) {
n.closest(".product_payments_btns").style.display = "none";
}
const available = document.querySelectorAll(
".swatch.clearfix .available"
);
const soldout = document.querySelectorAll(
".swatch.clearfix .soldout"
);
soldout.forEach((it) => (it.style.display = "none"));
if (available.length === 0) {
document.querySelector(".swatch.clearfix").style.display = "none";
}
};
}
}
case 57581600963: {
customStyle += `
#email-me-frame{font-family: synthese, sans-serif !important;}
#email-me-frame .frame-title {
padding-left: 0px !important;
color: #0d3860 !important;
font-size: 11px !important;
font-weight: 400 !important;
padding-top: 3px !important;
text-transform: capitalize;
}
#email-me-frame .frame-body-content {
font-weight: 300 !important;
font-size: 11px !important;
color: #0d3860 !important;
}
button .email-me-inlineButton {
font-weight: 400 !important;
border-width: 1px;
}`;
if (isCollPage) {
customStyle += `
#email-me-frame .email-frame-content {
border-radius: 0px !important;
border: 0 !important;
box-shadow: none !important;
}
#email-me-frame .frame-title {
padding-left: 0px !important;
font-family: synthese, sans-serif !important;
color: #0d3860 !important;
font-size: 16px !important;
font-weight: 400 !important;
padding-top: 0px;
padding-bottom: 6px;
text-transform: capitalize;
}`;
}
}
case 73514025266: {
if (themeId === 146007327026 && isCollPage) {
customStyle += `.product-restore-email {width: 80% !important;margin: 0 auto;}`;
}
break;
}
case 58193838255: {
if (isMobile && isCollPage) {
customStyle += `.email-me-button.email-me-inlineButton {
letter-spacing: 0px;
}`;
}
break;
}
case 53793915066: {
if (themeId === 136421834975) {
customStyle += `.product-restore-email{max-width:initial !important}`;
}
break;
}
case 23566876752: {
if (themeId === 122101039184) {
customStyle += `.rtl_true #email-me-frame .iti__flag-container{direction:ltr}.rtl_true #email-me-frame .iti__flag-container ul{direction:rtl}.rtl_true #email-me-frame .iti__flag-container .iti__flag-box{margin-left:6px}`;
}
break;
}
case 61285925123: {
customStyle += `#email-me-frame div.frame-title {
padding: 0 13px 0 0;
flex: initial;
}div.notify-type-toggler > div:nth-child(2) {
border-left: 1px solid var(--sa-border-color);
}.restore-email-wrapper {
width: 100%;
top: -30px;
}.collection-grid__wrapper .grid-item.grid-product {
flex-wrap: wrap;
}#email-me-frame div.email-frame-header {
justify-content: initial !important;
padding: 0 30px 0 0;
}.email-frame-body input::placeholder {
opacity: 1;
}#email-me-frame .email-footer-tips span {
color: #222;
}#email-me-frame .frame-close {
margin-right: 0 !important;
}#email-me-frame .close-box {
margin: 0 !important;
}`;
break;
}
case 11881800: {
customFeature = function () {
insertStyle.textContent += `button.custom_pers.product-add-to-cart-btn {
background-color: #fff !important;
color: #000;
}`;
inlineEmailDiv[0].insertAdjacentHTML(
"beforebegin",
`
GET NOTIFIED WHERE BACK IN STOCK
`
);
};
}
case 67088286014: {
customFeature = function () {
const frame = q("#email-me-frame");
if (frame) {
q(".frame-email-logo").innerHTML = `
`;
}
};
break;
}
case 52260241573: {
customFeature = function () {
const n = q("#email-me-frame .frame-submit");
if (n) {
n.insertAdjacentHTML(
"afterend",
`By signing up, you agree to receive promotional and marketing information from Mango People
`
);
}
};
break;
}
case 56661573841: {
customFeature = function () {
if (document.querySelector(".sms-type")) {
let me = new Event("click");
document.querySelector(".sms-type").dispatchEvent(me);
}
};
break;
}
case 71669449038: {
customFeature = function () {
qa(".email-frame-body input").forEach((i) =>
i.removeAttribute("type")
);
};
break;
}
case 72470462767: {
if (isProPage) {
customFeature = function () {
// Mark 产品页变体切换监听
// 选择要观察变动的节点
let targetNode;
if (shopId == 72470462767 && themeId === 158979948847) {
targetNode = q(
"section.page-width.section--padding.product.productSection"
);
if (targetNode) {
// 观察器的配置
const config = {
attributes: true,
childList: true,
subtree: true,
};
// 创建一个观察器实例并传入回调函数
const observer = new MutationObserver(
debounce(500, () => {
setTimeout(async () => {
const n = q(".product-restore-email");
if (!n) {
soldOutBtn = null;
insertEl = null;
selBtnStatus = 0;
insertStyle.textContent += `.email-me-button.email-me-inlineButton {
height: 60px !important;
}`;
qa("#email-me-frame,.successSub").forEach((it) =>
it.remove()
);
await init();
execute();
observer.disconnect();
}
}, 400);
})
);
// 以上述配置开始观察目标节点
observer.observe(targetNode, config);
}
}
};
} else if (isCollPage) {
customStyle += `.card-information__button button[disabled] {
display: none;}.restore-email-wrapper{width:100%}.product-restore-email,.product-restore-email .email-me-inlineButton{margin:0 !important}
.restore-email-wrapper+.item_cart_items {
display: none;
}.email-me-button.email-me-inlineButton {
font-weight: 600 !important;
}@media only screen and (max-width: 768px){
.email-me-button.email-me-inlineButton {
font-size: 12px !important;
}
}`;
}
break;
}
case 19073267: {
customFeature = function () {
if (q("#join-mailing-list")) {
q("#join-mailing-list").removeAttribute("checked");
}
};
break;
}
case 66072805644: {
customFeature = function () {
setTimeout(() => {
const n = q("#email-me-frame .buyer-phone");
if (n) {
n.placeholder = n.placeholder.substring(1);
}
}, 2000);
};
break;
}
case 66681012522:
case 76843450717:
case 55393976386: {
qa(
'.maxus-productdetail__options>.swatch[data-option-index="0"]>.soldout'
).forEach((item) => {
item.addEventListener("click", function () {
const color = q(
'.single-option-selector[data-option="option2"]'
).value;
const val = item.querySelector("input").value;
const title = val + " / " + color;
const variant = variantData.find(
(it) => it.title.indexOf(title) !== -1
);
if (variant) {
handleVariantChange(variant.id);
}
});
});
break;
}
case 48441458840: {
if (ShopifyAnalytics.meta.page.pageType === "collection") {
if (themeId === 137027780861) {
customStyle += `.quick-add__submit.button.button--full-width.button--secondary[disabled]{display:none}`;
}
customFeature = function () {
qa(".product-restore-email").forEach(
(i) => (i.parentNode.style.gridRowStart = 3)
);
};
break;
}
}
case 73761816874: {
collectionAccess = true;
}
}
}
})();